实际
pjax:history
react-router4+:两种模式,是动态路由(一般/之前 是静态路由),有exact匹配,而且可以在服务器端的使用
vuejs: 两种模式可以选择
angularjs/vue router,
单页应用 …
概述
最近一直在研究前后端分离,ajax可以很好的解决前后端分离的问题,但是又存在着浏览器无法前进后退,这个问题比较尴尬。但是采用前端路由的方式可以很好的解决这个问题。
路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同。
传统的网页根据用户访问的不同的地址,浏览器从服务器获取对应页面的内容展示给用户。这样造成服务器压力比较大,而且用户访问速度也比较慢。在这种场景下,出现了单页应用。
单页应用,就是只有一个页面,用户访问一个网址,服务器返回的页面始终只有一个,不管用户改变了浏览器地址栏的内容或者在页面内发生了跳转,服务器不会重新返回新的页面,而是通过相应的js操作来实现页面的更改。而地址栏内容的改变,显示不同的页面,实现的手段就是前端路由。
前端路由主要由两种方式实现:location.hash+hashchange事件,history.pushState()+popState事件
web路由
### 什么是路由
简单来说,路由就是URL到函数的映射。
### router和route的区别
route就是一条路由,它将一个URL路径和一个函数进行映射,例如:
### 服务器端路由
对于服务器来说,当接收到客户端发来的HTTP请求,会根据请求的URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。
对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。
对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。
### 客户端路由
对于客户端(通常为浏览器)来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。客户端路由最常见的有以下两种实现方案:
#### 1 基于Hash: location.hash+onhashchange事件
hash仅仅是客户端的一个状态,也就是说,当向服务器发请求的时候,hash部分并不会发过去。
#### 2 history: history.pushState/replaceState()+onpopState事件
通过HTML5 History API可以在不刷新页面的情况下,直接改变当前URL。
但是这种方法只能捕获前进或后退事件,无法捕获pushState和replaceState,一种最简单的解决方法是替换pushState方法,例如:1
2
3
4
5
6
7var pushState = history.pushState
history.pushState = function() {
pushState.apply(history, arguments)
// emit a event or just run a callback
emitEventOrRunCallback()
}
不过,最好的方法还是使用实现好的history库。
#### 两种实现的比较
总的来说,基于Hash的路由,兼容性更好;基于History API的路由,更加直观和正式。
但是,有一点很大的区别是,基于Hash的路由不需要对服务器做改动,基于History API的路由需要对服务器做一些改造。
### 五 动态路由
上面提到的例子都是静态路由,也就是说,路径都是固定的。但是有时候我们需要在路径中传入参数,例如获取某个用户的信息,我们不可能为每个用户创建一条路由,而是在通过捕获路径中的参数(例如用户id)来实现。
### 六 严格路由
在很多情况下,会遇到/foobar和/foobar/的情况,它们看起来非常类似,然而实际上有所区别,具体的行为也是视服务器设置而定。
## 其它
stateObj是会被持久化的硬盘上进行存储的,至少firefox是这么说的,我猜只要历史记录不销毁,它关联的stateObj就会一直存在。
$PS: react-router 路由state的状态 存储在sessionStorage里面
一、history.pushState和history.replaceState都不会触发这个事件
二、仅在浏览器前进后退操作、history.go/back/forward调用、hashchange的时候触发